<?php
declare (strict_types=1);

namespace app\api\controller;

use app\BaseController;
use app\common\tool\Result;
use Qiniu\Auth;
use Qiniu\Storage\UploadManager;
use think\exception\ValidateException;
use think\Response;

class Uploads extends BaseController
{
    //错误信息
    public $error;

    //允许上传格式
    protected $fileExt = 'jpg,png,gif,jpeg';

    //上传大小限制
    protected $filesize = '5242880';

    protected $regular = "/(3c25.*?28.*?29.*?253e)|(3c3f.*?28.*?29.*?3f3e)|(3C534352495054)|(2F5343524950543E)|(3C736372697074)|(2F7363726970743E)/is";

    public function uploadImage(): Response
    {
        $file = request()->file();
        try {
            $this->validate($file, ['file' => 'filesize:' . $this->filesize . '|fileExt:' . $this->fileExt . '']);
            $url = $this->app->config->get('filesystem.disks.public.url') . date('Ymd');
            $path = $this->app->config->get('filesystem.disks.public.root') . date('Ymd');
            $result = $file['file']->move($path, md5(date('YmdHis').rand(10000,99999)) . '.' . $file['file']->getOriginalExtension());
            $image = $url . '/' . $result->getFileName();
            if (!$this->illegalCheck($image)) {
                throw new \Exception($this->error);
            }
        } catch (ValidateException $e) {

            return Result::fail( $e->getMessage());
        }

        return Result::success('success', ['url' => $image]);
    }

    public function uploadVideo()
    {
        try {
            $config = config('qiniu');
            // 七牛云的密钥信息
            $accessKey = $config['accessKey'];
            $secretKey = $config['secretKey'];
            $bucket = $config['bucket'];

            // 初始化Auth状态
            $auth = new Auth($accessKey, $secretKey);
            // 要上传的文件路径
            $filePath = $_FILES['file']['tmp_name'];
            // 生成上传Token
            $token = $auth->uploadToken($bucket);

            // 初始化UploadManager类
            $uploadMgr = new UploadManager();

            // 调用uploadFileUploadedFile方法上传
            list($ret, $err) = $uploadMgr->putFile($token, null, $filePath);
            if ($err !== null) {
                return Result::fail('上传失败');
            }

            return Result::success('success', ['url' => $ret['key']]);
        } catch (ValidateException $e) {
            return Result::fail( $e->getMessage());
        }
    }

    /**
     * @param $disks -- 文件路径
     * @return bool
     * 验证图片是否含有非法文件
     */
    private function illegalCheck($disks): bool
    {
        $file = '.' . $disks;

        if (file_exists($file)) {
            $resource = fopen($file, 'rb');
            $fileSize = filesize($file);
            fseek($resource, 0);

            if ($fileSize > 512) {
                $hexCode = bin2hex(fread($resource, 512));
                fseek($resource, $fileSize - 512);
                $hexCode .= bin2hex(fread($resource, 512));
            } else { // 取全部
                $hexCode = bin2hex(fread($resource, $fileSize));
            }
            fclose($resource);

            $check = preg_match('#__HALT_COMPILER()#i', $hexCode)
                || preg_match('#/script>#i', $hexCode)
                || preg_match('#<([^?]*)\?php#i', $hexCode)
                || preg_match('#<\?\=#i', $hexCode);
            if ($check) {
                $this->error = '非法文件上传！';
                $this->remove($file);
                return false;
            }

            $result = preg_match($this->regular, $hexCode);

            if ($result) {
                $this->error = '非法文件上传！';
                $this->remove($file);
                return false;
            } else {
                return true;
            }
        } else {
            return false;
        }
    }

    /**
     * @param $disks -- 文件路径
     * @return bool
     * 删除文件
     */
    private function remove($file): bool
    {
        if (file_exists($file)) {
            unlink($file);
            return true;
        } else {
            return false;
        }
    }
}